Declaração de vetores.
vet_int <- c(5L, 23L, 58L, 47L)
vet_bool <- c(F, T, T, T)
vet_num <- c(109.1, 165.3, 147.7, 182.5)
vet_char<- c("Tim", "Bill", "Rosa", "Alex")[1] "integer"
[1] "logical"
[1] "numeric"
[1] "character"
[1] "complex"
Podemos verificar se os elementos do vetor vet_int são realmente inteiros.
[1] TRUE
Operações com vetores
[1] 10 46 116 94
[1] 32.08824 48.61765 43.44118 53.67647
[1] 12 30 65 54
[1] 8 27 59 50
Como os dois vetores não possuiam o mesmo tamanho, o vetor menor foi repetido até completar o vetor maior. Isso é chamado Reciclagem.
[1] "numeric"
[1] "character"
Podemos forçar um vetor a ser de um tipo específico
[1] -3 -2 -1 0 1 2
[1] "integer"
[1] -3 -2 -1 0 1 2
[1] "numeric"
[1] TRUE TRUE TRUE FALSE TRUE TRUE
[1] "logical"
[1] "-3" "-2" "-1" "0" "1" "2"
[1] "character"
Declaração de uma matriz 4*3
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
[4,] 10 11 12
Verificando a classe e as dimensões da matriz:
[1] "A classe é: matrix"
[1] "As dimensões da matriz são: 4 x 3"
Podemos criar uma matriz utilizando alguns dos vetores criados até agora.
[,1] [,2] [,3]
[1,] "Tim" "5" "109.1"
[2,] "Bill" "23" "165.3"
[3,] "Rosa" "58" "147.7"
[4,] "Alex" "47" "182.5"
Como matrizes aceitam apenas um tipo de dado, acabamos transformando todos os elementos no tipo character.
Podemos utilizar a primeira coluna como nome das linhas, dessa forma, as demais variáveis vão assumir o tipo numeric, que é mais abrangente do que o tipo integer
[,1] [,2]
Tim 5 109.1
Bill 23 165.3
Rosa 58 147.7
Alex 47 182.5
Agora, daremos nomes às colunas.
idade altura(cm)
Tim 5 109.1
Bill 23 165.3
Rosa 58 147.7
Alex 47 182.5
Subsets
idade altura(cm)
5.0 109.1
Tim Bill Rosa Alex
109.1 165.3 147.7 182.5
[1] 165.3
Matriz transposta
Tim Bill Rosa Alex
idade 5.0 23.0 58.0 47.0
altura(cm) 109.1 165.3 147.7 182.5
Multiplicação de matrizes
[,1] [,2] [,3] [,4]
[1,] 65 77 89 101
[2,] 86 102 118 134
[3,] 107 127 147 167
[4,] 128 152 176 200
Matriz inversa e diagonal principal
[,1] [,2]
[1,] 1 3
[2,] 2 4
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
[1] 1 4
Dataframes são similares à matrizes, mas possuem funções específicas como busca e indexação. Permitem que cada coluna seja de um tipo diferente.
df <- data.frame(vet_int, vet_num, row.names = vet_char)
colnames(df) <- c("idade", "altura(cm)")
df idade altura(cm)
Tim 5 109.1
Bill 23 165.3
Rosa 58 147.7
Alex 47 182.5
Verificando os tipos das colunas:
'data.frame': 4 obs. of 2 variables:
$ idade : int 5 23 58 47
$ altura(cm): num 109 165 148 182
Podemos adicionar mais uma coluna:
idade altura(cm) maioridade
Tim 5 109.1 FALSE
Bill 23 165.3 TRUE
Rosa 58 147.7 TRUE
Alex 47 182.5 TRUE
E uma nova linha
idade altura(cm) maioridade
Tim 5 109.1 FALSE
Bill 23 165.3 TRUE
Rosa 58 147.7 TRUE
Alex 47 182.5 TRUE
Pam 32 172.0 TRUE
As 2 primeiras linhas desse dataset:
idade altura(cm) maioridade
Tim 5 109.1 FALSE
Bill 23 165.3 TRUE
As duas últimas linhas:
idade altura(cm) maioridade
Alex 47 182.5 TRUE
Pam 32 172.0 TRUE
Listas permitem que cada elemento seja de um tipo de dado.
Um conjunto de listas do mesmo tamanho forma um dataset.
[[1]]
[1] "lista"
[[2]]
[1] 99
[[3]]
[1] 0.983
[[4]]
[1] FALSE
List of 4
$ : chr "lista"
$ : int 99
$ : num 0.983
$ : logi FALSE
Podemos criar uma lista com todos os vetores criados até agora
$boolean
[1] FALSE TRUE TRUE TRUE
$char
[1] "Tim" "Bill" "Rosa" "Alex"
[[3]]
[1] 0+1.5i 0+2.5i 0+3.5i 0+4.5i
[[4]]
[1] 5 23 58 47
[[5]]
[1] 109.1 165.3 147.7 182.5
List of 5
$ boolean: logi [1:4] FALSE TRUE TRUE TRUE
$ char : chr [1:4] "Tim" "Bill" "Rosa" "Alex"
$ : cplx [1:4] 0+1.5i 0+2.5i 0+3.5i ...
$ : int [1:4] 5 23 58 47
$ : num [1:4] 109 165 148 182
Subsets:
$boolean
[1] FALSE TRUE TRUE TRUE
[1] FALSE TRUE TRUE TRUE
[1] FALSE TRUE TRUE TRUE
Fatores servem para expressar variáveis categóricas.
temperatura <- c("frio", "calor", "ameno", "calor", "ameno", "frio")
temperatura.factor <- factor(temperatura, ordered = T, levels=c("frio", "ameno", "calor"))
temperatura.factor[1] frio calor ameno calor ameno frio
Levels: frio < ameno < calor
[1] 1 3 2 3 2 1
attr(,"levels")
[1] "frio" "ameno" "calor"
[1] "frio" "ameno" "calor"
dia_texto <- "01/08/2020 T 16:35:23"
dia_date <- as.Date(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia_date[1] "2020-08-01"
[1] 18475
POSIXct - número de segundos a partir de 01/01/1970
[1] "2020-08-01 16:35:23 -03"
[1] 1596310523
attr(,"tzone")
[1] "America/Sao_Paulo"
POSIXlt - Lista com elementos ano, mês, dia, hora, entre outros
[1] "2020-08-01 16:35:23 -03"
$sec
[1] 23
$min
[1] 35
$hour
[1] 16
$mday
[1] 1
$mon
[1] 7
$year
[1] 120
$wday
[1] 6
$yday
[1] 213
$isdst
[1] 0
$zone
[1] "-03"
$gmtoff
[1] NA
attr(,"tzone")
[1] "America/Sao_Paulo"
Como dia.time tem o elemeno chamado year, podemos fazer:
[1] 120
O pacote lubridate facilita a manipulação de datas
[1] "2020-08-01"
[1] "2020-08-01"
[1] "1999-07-04 13:07:52 UTC"
[1] 1999
[1] 52
[1] 1
[1] dom
Levels: dom < seg < ter < qua < qui < sex < sáb
[1] jul
12 Levels: jan < fev < mar < abr < mai < jun < jul < ago < set < ... < dez
Essas funções também podem ser usadas para atribuir componentes a datas:
[1] "2018-04-17 13:00:24 -03"
Fuso horário
[1] "America/Sao_Paulo"
[1] "2018-04-17 08:00:24 AKDT"
[1] "Asia/Singapore"
Operações com datas
data_inicio <- dmy("03/03/1986")
data_fim <- dmy("18/06/2017")
intervalo1 <- interval(data_inicio, data_fim)
intervalo1[1] 1986-03-03 UTC--2017-06-18 UTC
[1] "Interval"
attr(,"package")
[1] "lubridate"
Outras formas de obter o intervalo
Time difference of 11430 days
Time difference of 11430 days
Time difference of 987552000 secs
Time difference of 11430 days
É possível verificar se dois intervalos de tempo se sobrepõem
intervalo2 <- dmy("04-03-2000") %--% dmy("20/03/2018") # Operador %--% para intervalo
int_overlaps(intervalo1, intervalo2)[1] TRUE
Aritmética com datas
[1] "1d 0H 0M 0S"
[1] "86400s (~1 days)"
[1] "1986-03-04"
[1] "1988-03-03"
[1] "1986-04-03" "1986-05-03" "1986-06-03" "1986-07-03" "1986-08-03"
[6] "1986-09-03" "1986-10-03" "1986-11-03" "1986-12-03" "1987-01-03"
[11] "1987-02-03" "1987-03-03"
[1] 11430
[1] "11430d 0H 0M 0S"
Para obter números aleatórioa seguindo uma distribuição uniforme, em que a probabilidade de se gerar qualquer ponto contido no espaço amostral é proporcional ao tamanho do intervalo
set.seed(20)
margin.param <- list(
l = 50,
r = 25,
b = 10,
t = 10,
pad = 4
)
aleatorios <- ~runif(2000, min = 0, max = 3)
fig <- plot_ly(x = aleatorios, type = "histogram")
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
figx <- seq(0, 100, by = 1)
y <- punif(x, min = 10, max = 50)
fig <- plot_ly(x =x, y=y, mode = 'lines+markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
figamostra = c( "T", "R", "I", "A", "N", "G", "U", "L", "O", "S")
sample(amostra, replace = FALSE) #amostra sem repetição de valores [1] "L" "U" "R" "I" "S" "O" "T" "A" "G" "N"
[1] "R" "I" "R" "I" "U" "N" "O" "U" "G" "T"
[1] "U" "S" "S" "G" "O" "N" "N" "G" "N" "O" "N" "L" "R" "G" "N" "G" "N" "N" "U"
[20] "R"
Para fazer simulações, podemos usar as distribuições normal e binomial para amostras com valores mais “naturais”.
set.seed(902)
aleatorios <- data.frame(nums = rnorm(2000))
fig <- plot_ly(data = aleatorios, y=aleatorios$nums, type = 'scatter', mode = 'markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
figp <- ggplot(aleatorios, aes(nums)) +
geom_histogram(aes(y = ..density..), alpha = 0.7, fill = "#333333") +
geom_density(fill = "#ff4d4d", alpha = 0.5) +
theme(panel.background = element_rect(fill = '#ffffff'))
ggplotly(p) %>%
layout(autosize = F, width = 500, height = 300, margin = margin.param )aleatorios2 <- data.frame(nums = rnorm(2000, mean = 1, sd = 1.5))
aleatorios2$name <- 'mean=1,sd=1.5'
aleatorios3 <- data.frame(nums = rnorm(2000, mean = 2, sd = 3), name = 'mean=2,sd=3')
aleatorios$name <- 'mean=0,sd=1'
aleatorios.df <- rbind(aleatorios, aleatorios2, aleatorios3)
p <- ggplot(aleatorios.df, aes(nums, fill=name)) + geom_density(alpha = 0.2)
ggplotly(p) %>%
layout(autosize = F, width = 500, height = 300, margin = margin.param )Considerando o seguinte modelo linear: \[y=\beta_0+\beta_1x+\varepsilon\] em que \[\beta_0=0.5\] \[\beta_1=2.0\] \[x\sim \mathcal{N}(0;1^2)\] \[\varepsilon\sim \mathcal{N}(0; 2^2)\]
x<-0
if(x > 0){
sinal <- "positivo"
}else if(x == 0){
sinal <- "neutro"
}else{
sinal <- "negativo"
}
sinal[1] "neutro"
[1] "verdade"
acumulado <- c(0)
for(i in AirPassengers){
acumulado <- c(acumulado, tail(acumulado, 1)+i) #adiciona ao vetor a soma do último valor com a quantidade de passageiros do registro
}
acumulado <- acumulado[-1] #Remove o 0
acumulado [1] 112 230 362 491 612 747 895 1043 1179 1298 1402 1520
[13] 1635 1761 1902 2037 2162 2311 2481 2651 2809 2942 3056 3196
[25] 3341 3491 3669 3832 4004 4182 4381 4580 4764 4926 5072 5238
[37] 5409 5589 5782 5963 6146 6364 6594 6836 7045 7236 7408 7602
[49] 7798 7994 8230 8465 8694 8937 9201 9473 9710 9921 10101 10302
[61] 10506 10694 10929 11156 11390 11654 11956 12249 12508 12737 12940 13169
[73] 13411 13644 13911 14180 14450 14765 15129 15476 15788 16062 16299 16577
[85] 16861 17138 17455 17768 18086 18460 18873 19278 19633 19939 20210 20516
[97] 20831 21132 21488 21836 22191 22613 23078 23545 23949 24296 24601 24937
[109] 25277 25595 25957 26305 26668 27103 27594 28099 28503 28862 29172 29509
[121] 29869 30211 30617 31013 31433 31905 32453 33012 33475 33882 34244 34649
[133] 35066 35457 35876 36337 36809 37344 37966 38572 39080 39541 39931 40363
[1] 5.5
Podemos passar funções como parâmetros de outras funções
[1] 6
Podemos desenvolver nossas próprias funções. Por exemplo, a função fatorial recursiva.
[1] 120
[1] 3628800
library(readr)
Copas_Jogadores <- read_csv("data/Copas-Jogadores.csv",
col_types = cols(MatchID = col_integer(),
`Shirt Number` = col_integer()),
na = "NA", skip = 5)
Copas_Jogadores# A tibble: 37,779 x 9
`201` `1096` FRA `CAUDRON Raoul (~ S `0` `Ernest LIBERAT~ X8 X9
<dbl> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr> <chr>
1 201 1096 MEX LUQUE Juan (MEX) S 0 Rafael GARZA "C" ""
2 201 1096 FRA CAUDRON Raoul (F~ S 0 Andre MASCHINOT "" "G43~
3 201 1096 MEX LUQUE Juan (MEX) S 0 Hilario LOPEZ "" ""
4 201 1096 FRA CAUDRON Raoul (F~ S 0 Etienne MATTLER "" ""
5 201 1096 MEX LUQUE Juan (MEX) S 0 Dionisio MEJIA "" ""
6 201 1096 FRA CAUDRON Raoul (F~ S 0 Marcel PINEL "" ""
7 201 1096 MEX LUQUE Juan (MEX) S 0 Felipe ROSAS "" ""
8 201 1096 FRA CAUDRON Raoul (F~ S 0 Alex VILLAPLANE "C" ""
9 201 1096 MEX LUQUE Juan (MEX) S 0 Manuel ROSAS "" ""
10 201 1096 FRA CAUDRON Raoul (F~ S 0 Lucien LAURENT "" "G19~
# ... with 37,769 more rows
[1] "spec_tbl_df" "tbl_df" "tbl" "data.frame"
Para ler arquivo excel
library(openxlsx)
download.data('https://storage.googleapis.com/ds-publico/cameras.baltimore.xlsx')
baltimore <- read.xlsx("data/cameras.baltimore.xlsx")
str(baltimore)'data.frame': 80 obs. of 7 variables:
$ address : chr "S CATON AVE & BENSON AVE" "S CATON AVE & BENSON AVE" "WILKENS AVE & PINE HEIGHTS AVE" "THE ALAMEDA & E 33RD ST" ...
$ direction : chr "N/B" "S/B" "E/B" "S/B" ...
$ street : chr "Caton Ave" "Caton Ave" "Wilkens Ave" "The Alameda" ...
$ crossStreet : chr "Benson Ave" "Benson Ave" "Pine Heights" "33rd St" ...
$ intersection: chr "Caton Ave & Benson Ave" "Caton Ave & Benson Ave" "Wilkens Ave & Pine Heights" "The Alameda & 33rd St" ...
$ Lat : num 39.3 39.3 39.3 39.3 39.3 ...
$ Long : num -76.7 -76.7 -76.7 -76.6 -76.6 ...
O pacote dplyr possui funções que facilitam a manipulação de dados.
A função mutate adiciona uma coluna ao data frame
library(dplyr)
star.wars.modificado <- starwars %>%
mutate(imc = mass / ((height / 100) ^ 2))
star.wars.modificado %>% glimpse()Rows: 87
Columns: 15
$ name <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia...
$ height <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180...
$ mass <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, ...
$ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown"...
$ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light"...
$ eye_color <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blu...
$ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57....
$ sex <chr> "male", "none", "none", "male", "female", "male", "femal...
$ gender <chr> "masculine", "masculine", "masculine", "masculine", "fem...
$ homeworld <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan",...
$ species <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "H...
$ films <list> [<"The Empire Strikes Back", "Revenge of the Sith", "Re...
$ vehicles <list> [<"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, ...
$ starships <list> [<"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced ...
$ imc <dbl> 26.02758, 26.89232, 34.72222, 33.33007, 21.77778, 37.874...
# A tibble: 6 x 14
name height mass hair_color skin_color eye_color birth_year sex
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
1 C-3PO 167 75 <NA> gold yellow 112 none
2 R2-D2 96 32 <NA> white, blue red 33 none
3 R5-D4 97 32 <NA> white, red red NA none
4 IG-88 200 140 none metal red 15 none
5 R4-P17 96 NA none silver, red red, blue NA none
6 BB8 NA NA none none black NA none
gender homeworld species films vehicles starships
<chr> <chr> <chr> <list> <list> <list>
1 masculine Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
2 masculine Naboo Droid <chr [7]> <chr [0]> <chr [0]>
3 masculine Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
4 masculine <NA> Droid <chr [1]> <chr [0]> <chr [0]>
5 feminine <NA> Droid <chr [2]> <chr [0]> <chr [0]>
6 masculine <NA> Droid <chr [1]> <chr [0]> <chr [0]>
Rows: 25
Columns: 15
$ name <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Owen...
$ height <int> 172, 167, 96, 202, 178, 165, 97, 183, 175, 170, 180, 66,...
$ mass <dbl> 77, 75, 32, 136, 120, 75, 32, 84, 1358, 77, 110, 17, 75,...
$ hair_color <chr> "blond", NA, NA, "none", "brown, grey", "brown", NA, "bl...
$ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light"...
$ eye_color <chr> "blue", "yellow", "red", "yellow", "blue", "blue", "red"...
$ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 52.0, 47.0, NA, 24.0, 600.0, 21...
$ sex <chr> "male", "none", "none", "male", "male", "female", "none"...
$ gender <chr> "masculine", "masculine", "masculine", "masculine", "mas...
$ homeworld <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Tatooine",...
$ species <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "D...
$ films <list> [<"The Empire Strikes Back", "Revenge of the Sith", "Re...
$ vehicles <list> [<"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, ...
$ starships <list> [<"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced ...
$ imc <dbl> 26.02758, 26.89232, 34.72222, 33.33007, 37.87401, 27.548...
# A tibble: 87 x 4
name hair_color skin_color eye_color
<chr> <chr> <chr> <chr>
1 Luke Skywalker blond fair blue
2 C-3PO <NA> gold yellow
3 R2-D2 <NA> white, blue red
4 Darth Vader none white yellow
5 Leia Organa brown light brown
6 Owen Lars brown, grey light blue
7 Beru Whitesun lars brown light blue
8 R5-D4 <NA> white, red red
9 Biggs Darklighter black light brown
10 Obi-Wan Kenobi auburn, white fair blue-gray
# ... with 77 more rows
# A tibble: 25 x 9
name height mass birth_year sex gender homeworld species imc
<chr> <int> <dbl> <dbl> <chr> <chr> <chr> <chr> <dbl>
1 Luke Skywal~ 172 77 19 male mascul~ Tatooine Human 26.0
2 C-3PO 167 75 112 none mascul~ Tatooine Droid 26.9
3 R2-D2 96 32 33 none mascul~ Naboo Droid 34.7
4 Darth Vader 202 136 41.9 male mascul~ Tatooine Human 33.3
5 Owen Lars 178 120 52 male mascul~ Tatooine Human 37.9
6 Beru Whites~ 165 75 47 female femini~ Tatooine Human 27.5
7 R5-D4 97 32 NA none mascul~ Tatooine Droid 34.0
8 Biggs Darkl~ 183 84 24 male mascul~ Tatooine Human 25.1
9 Jabba Desil~ 175 1358 600 hermaph~ mascul~ Nal Hutta Hutt 443.
10 Wedge Antil~ 170 77 21 male mascul~ Corellia Human 26.6
# ... with 15 more rows
Nesse último filtro utilizamos ‘:’ para indicar uma sequência de colunas conhecidas e o ‘-’ para sinalizar que queríamos excluir as colunas com nomes terminados com ‘color’.
# A tibble: 87 x 5
name hair_color skin_color eye_color mass
<chr> <chr> <chr> <chr> <dbl>
1 Jabba Desilijic Tiure <NA> green-tan, brown orange 1358
2 Grievous none brown, white green, yellow 159
3 IG-88 none metal red 140
4 Darth Vader none white yellow 136
5 Tarfful brown brown blue 136
6 Owen Lars brown, grey light blue 120
7 Bossk none green red 113
8 Chewbacca brown unknown blue 112
9 Jek Tono Porkins brown fair blue 110
10 Dexter Jettster none brown yellow 102
# ... with 77 more rows
# A tibble: 87 x 2
name imc
<chr> <dbl>
1 Wat Tambor 12.9
2 Adi Gallia 14.8
3 Sly Moore 15.1
4 Roos Tarpals 16.3
5 Padmé Amidala 16.5
6 Lama Su 16.8
7 Jar Jar Binks 17.2
8 Ayla Secura 17.4
9 Shaak Ti 18.0
10 Barriss Offee 18.1
# ... with 77 more rows
#Agrupando, sumarizando e filtrando
starwars %>% group_by(species) %>% summarise( count = n(), mass = mean(mass, na.rm = TRUE) ) %>% filter(count > 1) %>% arrange(count)# A tibble: 9 x 3
species count mass
<chr> <int> <dbl>
1 Kaminoan 2 88
2 Mirialan 2 53.1
3 Twi'lek 2 55
4 Wookiee 2 124
5 Zabrak 2 80
6 Gungan 3 74
7 <NA> 4 48
8 Droid 6 69.8
9 Human 35 82.8
Primeiro, agrupamos por espécies, depois sumarizamos pelas colunas count, que utiliza a função ’n()’para apresentar o tamanho do grupo, e a coluna mass que apresenta a média da massa desse grupo, removendo os valores não disponíveis. O próximo passo foi filtrar para mostrar apenas os grupos com mais de 1 elemento, e por fim, ordenar as linhas de forma crescente, de acordo com a quantidade de elementos nos grupos.
---
title: "Estudo R"
output:
flexdashboard::flex_dashboard:
social: menu
source_code: embed
vertical_layout: fill
orientation: rows
---
```{r include=FALSE}
knitr::opts_chunk$set(echo = TRUE, error=TRUE)
#para limpar as variáveis do ambiente
rm(list = ls())
library(flexdashboard)
library(lubridate)
library(plotly)
```
Estruturas de dados
=======================================================================
Row {data-height=650 data-width=300 .tabset}
-------------------------------------
### Vetor
Declaração de vetores.
```{r}
vet_int <- c(5L, 23L, 58L, 47L)
vet_bool <- c(F, T, T, T)
vet_num <- c(109.1, 165.3, 147.7, 182.5)
vet_char<- c("Tim", "Bill", "Rosa", "Alex")
```
Também é possível declacar um vetor de números imaginários
```{r}
vet_img <- c(1.50i, 2.50i, 3.50i, 4.50i)
```
Verificando as classes dos vetores.
Nos vetores, todos os elementos são do mesmo tipo de dado.
```{r}
class(vet_int)
class(vet_bool)
class(vet_num)
class(vet_char)
class(vet_img)
```
Podemos verificar se os elementos do vetor vet_int são realmente inteiros.
```{r}
is.integer(vet_int)
```
Operações com vetores
```{r}
vet_int * 2 #multiplica cada elemento por 2
vet_num / 3.4
vet_int + 7
```
```{r}
vet_int + c(3, 4, 1)
```
Como os dois vetores não possuiam o mesmo tamanho, o vetor menor foi repetido até completar o vetor maior. Isso é chamado *Reciclagem*.
Vetores aceitam apenas um tipo de dado, na seguinte ordem de precedência:
character > complex > numeric > integer > logical
```{r}
x <- c(5L, 6.4)
class(x) # o vetor ficou como numérico
x <- c(5L, 6.4, "abc")
class(x) # o vetor passou a ser character
```
Podemos forçar um vetor a ser de um tipo específico
```{r}
x <- -3:2
x
class(x)
y <-as.numeric(x)
y
class(y)
y <- as.logical(x)
y # apenos 0 é false
class(y)
y <- as.character(x)
y
class(y)
```
### Matriz
Declaração de uma matriz 4*3
```{r}
matriz <- matrix(c(1:12), nrow = 4, ncol = 3, byrow = T)
matriz
```
Verificando a classe e as dimensões da matriz:
```{r}
paste("A classe é: ", class(matriz)[1] )
dimensoes <- dim(matriz)
paste("As dimensões da matriz são: ", dimensoes[1], "x", dimensoes[2])
```
Podemos criar uma matriz utilizando alguns dos vetores criados até agora.
```{r}
matriz2 <- matrix(c(vet_char, vet_int, vet_num), nrow = 4, byrow = F)
matriz2
```
Como matrizes aceitam apenas um tipo de dado, acabamos transformando todos os elementos no tipo *character*.
Podemos utilizar a primeira coluna como nome das linhas, dessa forma, as demais variáveis vão assumir o tipo *numeric*, que é mais abrangente do que o tipo *integer*
```{r}
matriz2 <- matrix(c(vet_int, vet_num), nrow = 4, byrow = F)
rownames(matriz2) <- vet_char
matriz2
```
Agora, daremos nomes às colunas.
```{r}
colnames(matriz2) <- c("idade", "altura(cm)")
matriz2
```
Subsets
```{r}
matriz2[1,] #seleciona a primeira linha
matriz2[,2] #seleciona a segunda coluna
matriz2[2,2] #seleciona o elemento da segunda linha e segunda coluna
```
Matriz transposta
```{r}
t(matriz2)
```
Multiplicação de matrizes
```{r}
m1 <- matrix(1:8, nrow = 4, ncol = 2)
m2 <- matrix(10:17, nrow = 2, ncol = 4)
m1 %*% m2
```
Matriz inversa e diagonal principal
```{r}
m1 <- matrix(1:4, nrow = 2, ncol = 2)
m1
solve(m1) # matriz inversa, a matriz tem que ser quadrada
diag(m1) #diagonal principal
```
### Dataframe
Dataframes são similares à matrizes, mas possuem funções específicas como busca e indexação.
Permitem que cada coluna seja de um tipo diferente.
```{r}
df <- data.frame(vet_int, vet_num, row.names = vet_char)
colnames(df) <- c("idade", "altura(cm)")
df
```
Verificando os tipos das colunas:
```{r}
str(df)
```
Podemos adicionar mais uma coluna:
```{r}
df <- cbind(df, maioridade = df$idade > 18)
df
```
E uma nova linha
```{r}
df <- rbind(df, "Pam" = list(32L, 172, TRUE))
df
```
As 2 primeiras linhas desse dataset:
```{r}
head(df, n=2)
```
As duas últimas linhas:
```{r}
tail(df, n=2)
```
### Lista
Listas permitem que cada elemento seja de um tipo de dado.
Um conjunto de listas do mesmo tamanho forma um dataset.
```{r}
lista1 <- list("lista", 99L, 0.983, F)
lista1
```
```{r}
str(lista1)
```
Podemos criar uma lista com todos os vetores criados até agora
```{r}
lista2 <- list("boolean"=vet_bool, "char"=vet_char, vet_img, vet_int, vet_num)
lista2
```
```{r}
str(lista2)
```
Subsets:
```{r}
lista2[1] #retorna uma sub-lista
lista2[[1]] #retorna o primeiro elemento da lista
lista2$boolean #filtra pelo nome do elemento
```
### Fator
Fatores servem para expressar variáveis categóricas.
```{r}
temperatura <- c("frio", "calor", "ameno", "calor", "ameno", "frio")
temperatura.factor <- factor(temperatura, ordered = T, levels=c("frio", "ameno", "calor"))
temperatura.factor
```
```{r}
unclass(temperatura.factor)
```
```{r}
levels(temperatura.factor)
```
Datas
=======================================================================
Data e hora
```{r}
dia_texto <- "01/08/2020 T 16:35:23"
dia_date <- as.Date(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia_date
unclass(dia_date) #valor representa (01/08/2020) - (01/01/1970) em dias
```
POSIXct - número de segundos a partir de 01/01/1970
```{r}
dia.time1 <- as.POSIXct(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia.time1
unclass(dia.time1) #valor representa (01/08/2020) - (01/01/1970) em segundos
```
POSIXlt - Lista com elementos ano, mês, dia, hora, entre outros
```{r}
dia.time2 <- as.POSIXlt(dia_texto,format="%d/%m/%Y T %H:%M:%S",tz="America/Sao_Paulo")
dia.time2
```
```{r}
unclass(dia.time2)
```
Como dia.time tem o elemeno chamado year, podemos fazer:
```{r}
dia.time2$year
```
O pacote lubridate facilita a manipulação de datas
```{r}
library(lubridate)
ymd("20200801") #Cria uma data sabendo que está na ordem ano, mês, dia
dmy("01.08.2020") #Cria uma data sabendo que está na ordem dia, mês, ano
```
```{r}
nascimento <- ymd_hms(19990704130752)
nascimento
year(nascimento) #ano da data
second(nascimento) #segundos da data
wday(nascimento) #dia da semana
wday(nascimento, label = T)
month(nascimento, label = T)
```
Essas funções também podem ser usadas para atribuir componentes a datas:
```{r}
dia1 <- ymd(20180417, tz = "America/Sao_Paulo")
hour(dia1) <- 13
second(dia1) <- 24
dia1
```
Fuso horário
```{r}
tz(dia1)
with_tz(dia1, tzone = "US/Alaska") #data/hora equivalente em outro timezone
dia1 <- force_tz(dia1, tz = "Asia/Singapore") #altera o timezone
tz(dia1)
```
Operações com datas
```{r}
data_inicio <- dmy("03/03/1986")
data_fim <- dmy("18/06/2017")
intervalo1 <- interval(data_inicio, data_fim)
intervalo1
class(intervalo1)
```
Outras formas de obter o intervalo
```{r}
data_fim - data_inicio
difftime(data_fim, data_inicio)
difftime(data_fim, data_inicio, unit="secs")
difftime(data_fim, data_inicio, unit="days")
```
É possível verificar se dois intervalos de tempo se sobrepõem
```{r}
intervalo2 <- dmy("04-03-2000") %--% dmy("20/03/2018") # Operador %--% para intervalo
int_overlaps(intervalo1, intervalo2)
```
Aritmética com datas
```{r}
days(1) #cria um dia
ddays(1) # cria uma duração de um dia em segundos
data_inicio + ddays(1)
data_inicio + years(2)
#Criar datas recorrentes
data_inicio + months(1:12)
#numero de dias em um intervalo
intervalo1 / days(1)
as.period(intervalo1, unit = "days")
```
Amostras e simulações
=======================================================================
Para obter números aleatórioa seguindo uma distribuição uniforme, em que a probabilidade de se gerar qualquer ponto contido no espaço amostral é proporcional ao tamanho do intervalo
#### Histograma distribuição uniforme
```{r}
set.seed(20)
margin.param <- list(
l = 50,
r = 25,
b = 10,
t = 10,
pad = 4
)
aleatorios <- ~runif(2000, min = 0, max = 3)
fig <- plot_ly(x = aleatorios, type = "histogram")
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
```
#### Probabilidade em uma distribuição uniforme
Avaliar a probabilidade uniforme de um valor no intervalo
```{r}
x <- seq(0, 100, by = 1)
y <- dunif(x, min = 10, max = 50)
fig <- plot_ly(x =x, y=y, mode = 'lines+markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
```
#### Probabilidade acumulada em uma distribuição uniforme
Avaliar a probabilidade acumulada uniforme de um valor dentro do intervalo
```{r}
x <- seq(0, 100, by = 1)
y <- punif(x, min = 10, max = 50)
fig <- plot_ly(x =x, y=y, mode = 'lines+markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
```
Para pegar uma amostra a partir de um domínio
```{r}
amostra = c( "T", "R", "I", "A", "N", "G", "U", "L", "O", "S")
sample(amostra, replace = FALSE) #amostra sem repetição de valores
sample(amostra, replace = TRUE) #amostra com repetição de valores
sample(amostra, size = 20, replace = T, prob = c(1,2,1,1,4,3,1,1,1,1)) #5 amostras
#as letras R,N e G estão com pesos maiores, com maior probabilidade de serem sorteados
```
Para fazer simulações, podemos usar as distribuições normal e binomial para amostras com valores mais "naturais".
#### Números aleatórios seguindo uma distribuição normal
```{r}
set.seed(902)
aleatorios <- data.frame(nums = rnorm(2000))
fig <- plot_ly(data = aleatorios, y=aleatorios$nums, type = 'scatter', mode = 'markers')
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
```
```{r}
p <- ggplot(aleatorios, aes(nums)) +
geom_histogram(aes(y = ..density..), alpha = 0.7, fill = "#333333") +
geom_density(fill = "#ff4d4d", alpha = 0.5) +
theme(panel.background = element_rect(fill = '#ffffff'))
ggplotly(p) %>%
layout(autosize = F, width = 500, height = 300, margin = margin.param )
```
Alterando os valores de média e desvio padrão, temos distribuições normais de diferentes formatos
```{r}
aleatorios2 <- data.frame(nums = rnorm(2000, mean = 1, sd = 1.5))
aleatorios2$name <- 'mean=1,sd=1.5'
aleatorios3 <- data.frame(nums = rnorm(2000, mean = 2, sd = 3), name = 'mean=2,sd=3')
aleatorios$name <- 'mean=0,sd=1'
aleatorios.df <- rbind(aleatorios, aleatorios2, aleatorios3)
p <- ggplot(aleatorios.df, aes(nums, fill=name)) + geom_density(alpha = 0.2)
ggplotly(p) %>%
layout(autosize = F, width = 500, height = 300, margin = margin.param )
```
#### Probabilidade em uma distribuição normal
Dada uma média e um desvio padrão, podemos avaliar a propabilidade da normal de um valor
```{r}
x <- seq(- 5, 5, by = 0.05)
y <- dnorm(x, mean = 0, sd=1)
ggplotly(p) %>%
layout(autosize = F, width = 500, height = 300, margin = margin.param )
```
#### Probabilidade acumulada em uma distribuição normal
Para avaliar a probabilidade acumulada da normal de um valor
```{r}
x <- seq(- 5, 5, by = 0.05)
y <- pnorm(x, mean = 0, sd = 1)
#plot_ly(x =x, y=y, mode = 'lines+markers')
```
#### Exemplo de simulação de um modelo linear
Considerando o seguinte modelo linear:
$$y=\beta_0+\beta_1x+\varepsilon$$
em que
$$\beta_0=0.5$$
$$\beta_1=2.0$$
$$x\sim \mathcal{N}(0;1^2)$$
$$\varepsilon\sim \mathcal{N}(0; 2^2)$$
```{r}
set.seed(346)
x = rnorm(200, mean = 0, sd = 1)
e = rnorm(200, mean = 0, sd = 2)
y = 0.5 + 2 * x + e
fig <- plot_ly( x = x, y = y, type = "scatter" )
fig <- fig %>% layout(autosize = F, width = 500, height = 300, margin = margin.param )
fig
```
Loops e Funções
=======================================================================
Row {data-height=650 data-width=300 .tabset}
-------------------------------------
### IF e ELSE
```{r}
x<-0
if(x > 0){
sinal <- "positivo"
}else if(x == 0){
sinal <- "neutro"
}else{
sinal <- "negativo"
}
sinal
```
```{r}
ifelse(1>0, "verdade", "mentira")
```
### Loops
Loop para calcular o valor acumulado de passageiros ao longo do tempo.
Os valores são armazenados em um vetor
```{r}
acumulado <- c(0)
for(i in AirPassengers){
acumulado <- c(acumulado, tail(acumulado, 1)+i) #adiciona ao vetor a soma do último valor com a quantidade de passageiros do registro
}
acumulado <- acumulado[-1] #Remove o 0
acumulado
```
### Funções
O R já possui muitas funções implementadas em suas bibliotecas como por exemplo a função mean(), que calcula a média.
```{r}
mean(1:10)
#View(mean) #Podemos ver a implementação dessas funções
```
Podemos passar funções como parâmetros de outras funções
```{r}
round(mean(1:10)) #Arredonda um valor numérico
```
Podemos desenvolver nossas próprias funções. Por exemplo, a função fatorial recursiva.
```{r}
fatorial <- function(n){
if(n==1 || n==0){
return(1)
}
return(n * fatorial(n-1))
}
fatorial(5)
fatorial(10)
```
Obtendo dados no R
=======================================================================
Row {data-height=650 data-width=300 .tabset}
-------------------------------------
### Download
Podemos fazer download de datasets da internet.
A função abaixo, verifica se a pasta 'data' existe, se não existir, cria a pasta e em seguida faz o download do arquivo passado na url e armazena nela.
```{r}
download.data <- function(file.url, file.local = NA){
if(!file.exists('data')){
dir.create('data')
}
if(is.na(file.local)){
file.local = file.path('./data', basename(file.url))
}
download.file(url = file.url, destfile = file.local , mode='wb')
}
```
Utilizando a função para baixar um arquivo csv
```{r}
download.data('https://storage.googleapis.com/ds-publico/Copas-Jogadores.csv')
```
### Leitura de arquivos
Para ler arquivos csv
```{r}
library(readr)
Copas_Jogadores <- read_csv("data/Copas-Jogadores.csv",
col_types = cols(MatchID = col_integer(),
`Shirt Number` = col_integer()),
na = "NA", skip = 5)
Copas_Jogadores
class(Copas_Jogadores)
```
Para ler arquivo excel
```{r}
library(openxlsx)
download.data('https://storage.googleapis.com/ds-publico/cameras.baltimore.xlsx')
baltimore <- read.xlsx("data/cameras.baltimore.xlsx")
str(baltimore)
```
Manipulação de dados
=======================================================================
Row {data-height=650 data-width=300 .tabset}
-------------------------------------
### Mutate
O pacote **dplyr** possui funções que facilitam a manipulação de dados.
A função mutate adiciona uma coluna ao data frame
```{r}
library(dplyr)
star.wars.modificado <- starwars %>%
mutate(imc = mass / ((height / 100) ^ 2))
star.wars.modificado %>% glimpse()
```
### Filter
Para filtrar os dados de um data frame
```{r}
starwars %>% filter(species == "Droid") %>% print(n = 10, width = Inf)
star.wars.modificado %>% filter(imc > 25) %>% glimpse()
```
### Select
Para ordenar e filtrar colunas
```{r}
starwars %>% select(name, ends_with("color"))
star.wars.modificado %>% filter(imc > 25) %>% select(name:species, -ends_with("color"), imc)
```
Nesse último filtro utilizamos ':' para indicar uma sequência de colunas conhecidas e o '-' para sinalizar que queríamos excluir as colunas com nomes terminados com 'color'.
### Arrange
Utilizado para reodenar as linhas de um data frame
```{r}
starwars %>% arrange(desc(mass)) %>% select(name, ends_with("color"), mass)
star.wars.modificado %>% arrange(imc) %>% select(name, imc)
```
### Agregações
```{r}
#Agrupando, sumarizando e filtrando
starwars %>% group_by(species) %>% summarise( count = n(), mass = mean(mass, na.rm = TRUE) ) %>% filter(count > 1) %>% arrange(count)
```
Primeiro, agrupamos por espécies, depois sumarizamos pelas colunas count, que utiliza a função 'n()'para apresentar o tamanho do grupo, e a coluna mass que apresenta a média da massa desse grupo, removendo os valores não disponíveis.
O próximo passo foi filtrar para mostrar apenas os grupos com mais de 1 elemento, e por fim, ordenar as linhas de forma crescente, de acordo com a quantidade de elementos nos grupos.